// 全局组件Toast （通过Portal + createContext实现）
// 避免样式污染，灵活性高，需手动管理状态，适用复杂应用，多弹窗场景
// 使用方式：在根组件包裹ToastProvider，任意子组件通过useToast调用

import React, { createContext, useContext, useReducer, useState } from "react"
import { createPortal } from "react-dom"

const ToastContext = createContext() // 创建Context对象,用于传递数据

const initialState = { toasts: [] } // 初始状态

function reducer(state, action) {
    switch (action.type) {
        case "ADD_TOAST":
            return { toasts: [...state.toasts, action.payload] }
        case "REMOVE_TOAST":
            return { toasts: state.toasts.filter((t) => t.id !== action.payload) }
        default:
            return state
    }
}

export function ToastProvider({ children }) {
    const [state, dispatch] = useReducer(reducer, initialState)

    const addToast = (...args) => {
        let options = {
            message: "",
            type: "info", // success, info, error
            duration: 3000,
        }
        let props = args[0] // 看第一个参数是对象还是字符串，如果是字符串，则认为是message
        if (typeof props === "string") {
            options = { message: args[0], type: args[1] || options.type, duration: args[2] || options.duration}
        } else {
            let { message, type, duration } = props
            options = { message, type: type || options.type, duration: duration || options.duration }
        }
        
        const id = Date.now()
        dispatch({ type: "ADD_TOAST", payload: { ...options, id} })
        setTimeout(() => dispatch({ type: "REMOVE_TOAST", payload: id }), options.duration)
    }

    return (
        <ToastContext.Provider value={{ addToast }}>
            {children}
            {createPortal(
                <div className="toast-container">
                    {state.toasts.map((toast) => (
                        <Toast key={toast.id} {...toast} />
                    ))}
                </div>,
                document.body
            )}
        </ToastContext.Provider>
    )
}

function Toast({ id, message, type }) {
    return <div className={`toast ${type}`}>{message}</div>
}

export function useToast() {
    return useContext(ToastContext)
}
